package com.example.myvolley;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * Created by edmond on 16-4-11.
 */
public class MyUploadRequest extends StringRequest{
    private Response.Listener listener;
    private Response.ErrorListener errorListener;

    private final static String BOUNDARY = "---------------------------3721751712076501785172162657"; //数据分隔线
    private final static String MULTIPART_FORM_DATA = "multipart/form-data";

    private String file;

    private int reqWidth;
    private int reqHeight;

    public MyUploadRequest(String url, String file,Response.Listener<String> listener, Response.ErrorListener errorListener) {
        this(url, file,listener, errorListener,0,0);
    }

    public MyUploadRequest(int method, String url, String file,Response.Listener<String> listener, Response.ErrorListener errorListener) {
        this(Method.POST,url, file,listener, errorListener,0,0);
    }

    public MyUploadRequest(String url, String file,Response.Listener<String> listener, Response.ErrorListener errorListener,int reqWidth,int reqHeight) {
        this(Method.POST,url, file,listener, errorListener,reqWidth,reqHeight);
    }

    public MyUploadRequest(int method, String url, String file,Response.Listener<String> listener, Response.ErrorListener errorListener,int reqWidth,int reqHeight) {
        super(method, url, listener, errorListener);
        this.listener = listener;
        this.errorListener = errorListener;
        setShouldCache(false);
        this.file = file;
        setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        this.reqWidth = reqWidth;
        this.reqHeight = reqHeight;
    }

    /**
     * 这里开始解析数据
     * @param response Response from the network
     * @return
     */
    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        try {
            String mString =
                    new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            Log.v("zgy", "====mString===" + mString);

            return Response.success(mString,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        }
    }

    /**
     * 回调正确的数据
     * @param response The parsed response returned by
     */
    @Override
    protected void deliverResponse(String response) {
        listener.onResponse(response);
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        if (file == null|| file.equals("")){
            return super.getBody() ;
        }else{
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            StringBuffer sb = new StringBuffer();
            /*第一行*/
            //`"--" + BOUNDARY + "\r\n"`
            sb.append("--"+BOUNDARY);
            sb.append("\r\n") ;
            /*第二行*/
            //Content-Disposition: form-data; name="参数的名称"; filename="上传的文件名" + "\r\n"
            sb.append("Content-Disposition: form-data;");
            sb.append(" name=\"");
            sb.append("file") ;
            sb.append("\"") ;
            sb.append("; filename=\"") ;
            sb.append(file.substring(file.lastIndexOf('/'))) ;
            sb.append("\"");
            sb.append("\r\n") ;
            /*第三行*/
            //Content-Type: 文件的 mime 类型 + "\r\n"
            sb.append("Content-Type: ");
            if(reqHeight<=0||reqWidth<=0){
                sb.append(file.substring(file.lastIndexOf(".")));
            }else{
                sb.append("image/jpg") ;//should write a function to get file's type according filename
            }
            sb.append("\r\n") ;
            /*第四行*/
            //"\r\n"
            sb.append("\r\n") ;
            try {
                bos.write(sb.toString().getBytes("utf-8"));

                if(reqHeight<=0||reqWidth<=0){
                    byte[] b = new byte[1024*4];
                    int len;
                    FileInputStream fileInputStream = new FileInputStream(new File(file));
                    while((len=fileInputStream.read(b))!=-1){
                        bos.write(b,0,len);
                    }
                }else{
                    byte[] bitmapData = getSmallBitmap(file);
                    bos.write(bitmapData);
                    //bos.write();//write file to bos
                }
                bos.write("\r\n".getBytes("utf-8"));
                /*结尾行*/
                //`"--" + BOUNDARY + "--" + "\r\n"`
                String endLine = "--" + BOUNDARY + "--" + "\r\n" ;
                bos.write(endLine.toString().getBytes("utf-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bos.toByteArray();
        }
    }

    @Override
    public String getBodyContentType() {
        return MULTIPART_FORM_DATA+"; boundary="+BOUNDARY;
    }

    private byte[] getSmallBitmap(String filePath) {

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqHeight, reqWidth);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        Bitmap bm = BitmapFactory.decodeFile(filePath, options);
        if(bm == null){
            return  null;
        }

        ByteArrayOutputStream baos = null ;

        try{
            baos = new ByteArrayOutputStream();
            bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            byte[] bitmapdata = baos.toByteArray();

            return bitmapdata;
        }finally{
            try {
                if(baos != null)
                    baos.close() ;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private int calculateInSampleSize(BitmapFactory.Options options,
                                             int reqHeight, int reqWidth) {
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;

        if(height>width){
            int temp = height;
            height = width;
            width = temp;
        }

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
        }
        return inSampleSize;
    }
}
